/**
 * WTF Engine
 *
 * License... etc.
 **
 * SDL Graphics Implementation
 **
 * Authors: Dan Horgan
 **/

#ifndef __graphics_sdlH__
#define __graphics_sdlH__

#include "config.h"

#ifdef __WM_SDL__

#ifdef __graphics_impl__
#	error Graphics already implemented
#else
#	define __graphics_impl__
#endif

#include "sdlmisc.h"
#include "vector.h"
#include "aux-math.h"
#include "wtftypes.h"
#include "data.h"

namespace WtfGraphics {

	// The Canvas class, for objects which can be drawn on
	class Canvas : public WtfEngine::DataObject
	{

		protected:
			// SDL surface
			SDL_Surface *surface;

		public:
			// Constructor
			Canvas();
			Canvas(iVector2D dim);
			Canvas(SDL_Surface *s);

			// Destructor
			virtual ~Canvas();

			iVector2D dim() const;

			// Centers the destination rect to a SDL surface
			//void CenterDestRect(SDL_Surface *surface);
			// Sets position of the destination rect
			//void SetDestPosition(iVector2D);

			// Draws the image onto another surface
			//void DrawOn(SDL_Surface *surface);
			// Draws the image onto another surface, specifying position as well
			//void DrawOnAt(SDL_Surface *surface, iVector2D);

			/*
			void putCanvas(Canvas *c, iVector2D pos);
			void putPixel(iVector2D pos, Colour c);
			void putCircle(iVector2D pos, tScalar r, Colour c);
			void putLine(iLineSegment *l, Colour c);
			void putGradientLine(iLineSegment l, Colour c1, Colour c2);*/
			SDL_Surface *getSurface();

			// frees surface memory
			void Unload();

			int lockSurface()
			{
				if (SDL_MUSTLOCK(surface)) 
				{
					return SDL_LockSurface(surface);
				} else { return 0; }
			};

			void unlockSurface()
			{
				if (SDL_MUSTLOCK(surface)) 
					SDL_UnlockSurface(surface);
			};

			typedef WtfEngine::GcReference<Canvas>	tCanvasRef;
	};

	class Screen : public Canvas, IMPLEMENTS(Screen)
	{
		private:
			static Screen *	MainScreen;

		public:
			Screen()
				: Canvas() {
					if(MainScreen) throw "Screen already exists";
					MainScreen = this;
				};

			virtual ~Screen() {};

			void SetMode(const GraphicsMode& mode);
			void InitGL();
			void UpdateScreen();

			void clearScreen();
			//void putPoint(tVector pos, Colour c);
			//void putLine(tVector p1, tVector p2, Colour c);
			//void putGradientLine(tVector p1, tVector p2, Colour c1, Colour c2);
			//void putMesh(Mesh& obj, tVector pos, Orientation3D ori, Colour c);
			//void putObject(GameObject& obj, Colour c);

			void Activate();
			void Deactivate();

			int getWindowHandle() const;

			iVector2D getSize() const {
				return dim();
			};

			static Screen * GetScreen() {
				return MainScreen;
			};
	};

	typedef WtfEngine::GcReference<Screen>	tScreenRef;

	// The Image class for loading and rendering image files
	class Image : public Canvas
	{
		public:
			typedef WtfEngine::GcReference<Image>	tImageReference;

			virtual ~Image() {};

			// Loads a BMP file
			void LoadBMP(char *path);
	};
};

#endif
#endif
